package dao

import (
	"fmt"
	"time"

	"cron-go/internal/pkg/crontab/models"
	"cron-go/internal/pkg/database/mysql"

	"github.com/go-liam/util/conv"
	"github.com/go-liam/util/response"
)

var TaskDaoServer = new(TaskDao)

type TaskDao struct {
}

func (e *TaskDao) FindOneByName(name string) (*models.TaskMysqlModel, error) {
	item := new(models.TaskMysqlModel)
	sql := "select * from cron_task where name =?  and is_delete =0 limit 1 "
	v := mysql.GetDB(mysql.DB_NAME).Raw(sql, name).Scan(item)
	return item, v.Error
}

func (e *TaskDao) FindOneByID(id int64) (*models.TaskMysqlModel, error) {
	item := new(models.TaskMysqlModel)
	sql := "select * from cron_task where id =?  and is_delete =0 limit 1 "
	v := mysql.GetDB(mysql.DB_NAME).Raw(sql, id).Scan(item)
	return item, v.Error
}

func (e *TaskDao) Create(item *models.TaskMysqlModel) (int64, error) {
	item.CreatedAt = time.Now().Unix()
	item.UpdatedAt = item.CreatedAt
	item.DoUpdatedAt = item.CreatedAt
	v := mysql.GetDB(mysql.DB_NAME).Create(item)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) FindMulti(p *response.Pagination, s *response.ListParameter) ([]*models.TaskMysqlModel, error) {
	var result []*models.TaskMysqlModel
	sqlLimit := fmt.Sprintf(" limit %d , %d  ", (p.Current-1)*p.PageSize, p.PageSize)
	sqlWhere := " is_delete = 0 " + s.WhereSt
	sql := "select * from cron_task where " + sqlWhere + s.OrderSt + sqlLimit
	mysql.GetDB(mysql.DB_NAME).Model(&models.TaskMysqlModel{}).Where(sqlWhere).Count(&p.Total)
	v := mysql.GetDB(mysql.DB_NAME).Raw(sql).Scan(&result)
	return result, v.Error
}

func (e *TaskDao) FindAll(s *response.ListParameter) ([]*models.TaskMysqlModel, error) {
	var result []*models.TaskMysqlModel
	sqlWhere := " is_delete = 0 " + s.WhereSt
	sql := "select * from cron_task where " + sqlWhere + s.OrderSt
	v := mysql.GetDB(mysql.DB_NAME).Raw(sql).Scan(&result)
	return result, v.Error
}

func (e *TaskDao) FindByIDs(ids []int64) ([]*models.TaskMysqlModel, error) {
	var result []*models.TaskMysqlModel
	sql := fmt.Sprintf("select * from cron_task where `id` in (%v) ", conv.ArrayToString(ids, ","))
	v := mysql.GetDB(mysql.DB_NAME).Raw(sql).Scan(&result)
	return result, v.Error
}

func (e *TaskDao) Update(i *models.TaskMysqlModel) (int64, error) {
	date := time.Now().Unix()
	sql := "update `cron_task` set `name` = ?,`updated_at` = ?,`spec`=?,`command`=?,`config`=? ,`is_notify`=? ,`notify_config`=? ,`worker_type`= ? ,`label`= ? where `id` = ? "
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql, i.Name, date, i.Spec, i.Command, i.Config, i.IsNotify, i.NotifyConfig, i.WorkerType, i.Label, i.ID)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) UpdateStatus(ids []int64, status int) (int64, error) {
	date := time.Now().Unix()
	sql := fmt.Sprintf("update `cron_task` set `status` = ? ,`updated_at` = ? where `id` in (%v) ", conv.ArrayToString(ids, ","))
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql, status, date)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) UpdateDoStatus(ids []int64, status int) (int64, error) {
	date := time.Now().Unix()
	sql := fmt.Sprintf("update `cron_task` set `do_status` = ? ,`do_updated_at` = ? where `id` in (%v) ", conv.ArrayToString(ids, ","))
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql, status, date)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) UpdateNotifyStatus(ids []int64, status int) (int64, error) {
	date := time.Now().Unix()
	sql := fmt.Sprintf("update `cron_task` set `notify_status` = ? ,`do_updated_at` = ? where `id` in (%v) ", conv.ArrayToString(ids, ","))
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql, status, date)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) Delete(ids []int64) (int64, error) {
	date := time.Now().Unix()
	sql := fmt.Sprintf("update `cron_task` set `is_delete` = ? ,`updated_at` = ? where `id` in (%v) and `is_delete`= 0 ", conv.ArrayToString(ids, ","))
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql, 1, date)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) Clear() (int64, error) {
	date := time.Now().Unix() - 1*60*60*24
	sql := fmt.Sprintf(" delete from `cron_task` where `id` > 0 and `is_delete` = 1 and `updated_at` < %v ; ", date)
	println(sql)
	v := mysql.GetDB(mysql.DB_NAME).Exec(sql)
	return v.RowsAffected, v.Error
}

func (e *TaskDao) GetTaskByList(id int64, list []*models.TaskMysqlModel) *models.TaskMysqlModel {
	for _, i := range list {
		if i.ID == id {
			return i
		}
	}
	return nil
}
